<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>介绍</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="indexes.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="indexes.html">快退</a></td><td width="60%" align="center" valign="bottom">章11. 索引</td><td width="10%" align="right" valign="top"><a href="indexes.html">快进</a></td><td width="10%" align="right" valign="top"><a href="indexes-types.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="INDEXES-INTRO">11.1. 介绍</a></h1>
<p>假设有像下面这样一个表：</p>
<pre class="PROGRAMLISTING">CREATE TABLE test1 (
    id integer,
    content varchar
);</pre>
<p>需要大量使用下面这样的语句进行查询：</p>
<pre class="PROGRAMLISTING">SELECT content FROM test1 WHERE id = <tt class="REPLACEABLE"><i>constant</i></tt>;</pre>
<p>通常，数据库系统不得不一行一行地扫描整个 <tt class="STRUCTNAME">test1</tt> 表以寻找所有匹配的记录。如果在 <tt class="STRUCTNAME">test1</tt> 里面有许多行，但是只返回少数几行(可能是零行或一行)，那么上面这个方法可就很差劲了。如果我们让数据库系统在 <tt class="STRUCTFIELD">id</tt> 列上维护一个索引用于定位匹配的行。这样，数据库系统只需要在搜索树中走少数的几层就可以找到匹配行。</p>
<p>在大多数非小说的书籍里面都使用了类似这样的方法：在书的背后收集着读者会经常查找的术语和概念的索引，并按照字母顺序排列。有兴趣的读者可以快速地扫描该索引并且切换到合适的页，因此不用阅读整本书就能查找到感兴趣的位置。作者的任务之一就是预计哪些项是读者最需要查找的东西，与之类似，预计哪些索引可以带来便利也是数据库程序员的任务。</p>
<p>下面的命令可以用于在 <tt class="STRUCTFIELD">id</tt> 列上创建前面讨论过的索引：</p>
<pre class="PROGRAMLISTING">CREATE INDEX test1_id_index ON test1 (id);</pre>
<p>索引名字 <tt class="STRUCTNAME">test1_id_index</tt> 可以自由选择，但是应该选那些稍后可以让你回忆起索引含义的名字。</p>
<p>要删除一个索引，使用 <tt class="COMMAND">DROP INDEX</tt> 命令。你可以在任何时候向表里增加索引或者从表中删除索引。</p>
<p>一旦你创建了索引，那么就不需要更多干涉了：当系统认为用索引比顺序的表扫描快的时候它就会使用索引。不过你可能必须经常性地运行 <tt class="COMMAND">ANALYZE</tt> 命令以更新统计信息，好让查询规划器能够做出有训练有素的判断。参见<a href="performance-tips.html">章13</a>获取关于如何获知是否使用了索引的信息，以及在什么时候、什么原因下规划器会决定<span class="emphasis"><i class="EMPHASIS">不</i></span>使用索引。</p>
<p>索引对带搜索条件的 <tt class="COMMAND">UPDATE</tt> 和 <tt class="COMMAND">DELETE</tt> 命令也有好处。索引更可以用于表连接查询。因此，如果你定义了索引的列是连接条件的一部分，那么它可以显著提高连接的查询速度。</p>
<p>在一个巨大的表上创建索引可能会消耗大量的时间。缺省时，PostgreSQL 允许在创建索引的同时读取表(select)，但是写入表(insert, update, delete)的动作将被阻塞到索引创建完毕。在生产环境下这种阻塞通常是不可接受的，因此也允许在创建索引的同时写入表，但是有一些警告需要注意，更多信息参见<a href="sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY"><i>并行创建索引</i></a>。</p>
<p>创建索引之后，它必须和表保持同步。这些操作增加了数据操作的负荷。因此我们应该把那些非关键或者根本用不上的索引删除掉。</p>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="indexes.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="indexes-types.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">索引</td><td width="34%" align="center" valign="top"><a href="indexes.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">索引类型</td></tr>
</table>
</div>
</body></html>